// Created by wangliang on 2025/4/16.

import 'dart:convert';
import 'dart:typed_data';

import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';

class AESUtils {
  static String encryptCBCPKCS7(String secret, String content) {
    final secretHex = _stringToHex(secret);
    if (secretHex.length < 32) {
      throw ArgumentError('Secret too short to derive IV');
    }

    if (![32, 48, 64].contains(secretHex.length)) {
      throw ArgumentError('Invalid secret length. Must be 16/24/32 bytes (hex: 32/48/64 chars)');
    }
    final keyBytes = hex.decode(secretHex);
    final ivBytes = hex.decode(secretHex.substring(0, 32));
    Key key = Key(Uint8List.fromList(keyBytes));
    IV iv = IV(Uint8List.fromList(ivBytes));
    final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));
    final encrypted = encrypter.encrypt(content, iv: iv);
    return encrypted.base64;
  }

  static String encryptBytesCBCPKCS7(String secret, List<int> bytes) {
    final secretHex = _stringToHex(secret);
    if (secretHex.length < 32) {
      throw ArgumentError('Secret too short to derive IV');
    }

    if (![32, 48, 64].contains(secretHex.length)) {
      throw ArgumentError('Invalid secret length. Must be 16/24/32 bytes (hex: 32/48/64 chars)');
    }
    final keyBytes = hex.decode(secretHex);
    final ivBytes = hex.decode(secretHex.substring(0, 32));
    Key key = Key(Uint8List.fromList(keyBytes));
    IV iv = IV(Uint8List.fromList(ivBytes));
    final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));
    final encrypted = encrypter.encryptBytes(bytes, iv: iv);
    return encrypted.base64;
  }

  static String decryptCBCPKCS7(String secret, String encryptedBase64) {
    final secretHex = _stringToHex(secret);

    if (secretHex.length < 32) {
      throw ArgumentError('Secret too short to derive IV');
    }

    if (![32, 48, 64].contains(secretHex.length)) {
      throw ArgumentError('Invalid secret length. Must be 16/24/32 bytes (hex: 32/48/64 chars)');
    }

    final keyBytes = hex.decode(secretHex);
    final ivBytes = hex.decode(secretHex.substring(0, 32));

    final key = Key(Uint8List.fromList(keyBytes));
    final iv = IV(Uint8List.fromList(ivBytes));

    final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));
    final decrypted = encrypter.decrypt64(encryptedBase64, iv: iv);

    return decrypted;
  }

  static String _stringToHex(String input) {
    // 将字符串编码为 UTF-8 字节数组
    List<int> bytes = input.codeUnits;
    StringBuffer buffer = StringBuffer();
    for (int byte in bytes) {
      // 将每个字节转换为两位的十六进制字符串
      buffer.write(byte.toRadixString(16).padLeft(2, '0'));
    }
    return buffer.toString();
  }

  static String calculateMd5(String input) {
    // 将输入字符串编码为 UTF-8 字节
    var bytes = utf8.encode(input);
    // 计算 MD5 哈希值
    var digest = md5.convert(bytes);
    // 将哈希值转换为十六进制字符串
    return digest.toString();
  }
}
